/*
 * Copyright (C) 2011 Jesus Navalon i Pastor <jnavalon at redhermes dot net>
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

/*
 * pn_Hvs.java
 *
 * Created on 22/09/2011, 01:19:53
 */
package kuasar.plugin.servermanager.gui.infoserver;

import java.awt.Component;
import java.awt.event.ItemEvent;
import javax.swing.JList;
import kuasar.plugin.utils.Connection;
import kuasar.plugin.utils.Connection.CMD;
import kuasar.plugin.utils.SSocketTools;
import kuasar.plugin.utils.SSocketTools.IllegalStatement;
import kuasar.plugin.utils.Server;
import kuasar.plugin.utils.dialogs.dg_KeyStore;
import kuasar.plugin.utils.dialogs.dg_Username;
import kuasar.plugin.utils.pn_Info;
import java.io.IOException;
import java.util.ArrayList;
import javax.swing.DefaultComboBoxModel;
import javax.swing.Icon;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.ListCellRenderer;
import kuasar.plugin.servermanager.Config;

/**
 *
 * @author Jesus Navalon i Pastor <jnavalon at redhermes dot net>
 */
public class pn_Hvs extends JPanel {

    private char[] kspwd, userpwd;
    private String ks, user, address;
    private int port;

    public pn_Hvs(String address, String port) {
        this.address = address;
        try {
            this.port = Integer.parseInt(port);
        } catch (NumberFormatException ex) {
            this.port = Config.GlobalServerCFG.port;
        }
        initComponents();
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        cmb_hvs = new javax.swing.JComboBox();
        pn_hv = new javax.swing.JPanel();

        setOpaque(false);

        cmb_hvs.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "---" }));
        cmb_hvs.addItemListener(new java.awt.event.ItemListener() {
            public void itemStateChanged(java.awt.event.ItemEvent evt) {
                cmb_hvsItemStateChanged(evt);
            }
        });

        pn_hv.setOpaque(false);
        pn_hv.addComponentListener(new java.awt.event.ComponentAdapter() {
            public void componentResized(java.awt.event.ComponentEvent evt) {
                pn_hvComponentResized(evt);
            }
        });

        javax.swing.GroupLayout pn_hvLayout = new javax.swing.GroupLayout(pn_hv);
        pn_hv.setLayout(pn_hvLayout);
        pn_hvLayout.setHorizontalGroup(
            pn_hvLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 567, Short.MAX_VALUE)
        );
        pn_hvLayout.setVerticalGroup(
            pn_hvLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 378, Short.MAX_VALUE)
        );

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
        this.setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                    .addComponent(pn_hv, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(cmb_hvs, javax.swing.GroupLayout.PREFERRED_SIZE, 210, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addContainerGap())
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(cmb_hvs, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(pn_hv, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addContainerGap())
        );
    }// </editor-fold>//GEN-END:initComponents

    private void pn_hvComponentResized(java.awt.event.ComponentEvent evt) {//GEN-FIRST:event_pn_hvComponentResized
        if(pn_hv.getComponentCount()>0){
            pn_hv.getComponent(0).setBounds(0, 0, pn_hv.getWidth(), pn_hv.getHeight());
        }
        pn_hv.updateUI();
    }//GEN-LAST:event_pn_hvComponentResized

    private void cmb_hvsItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_cmb_hvsItemStateChanged
        if(evt.getStateChange() == ItemEvent.SELECTED){
            String[] selected = (String[]) cmb_hvs.getSelectedItem();
            if(selected[0]==null){
                loadServerPanel();
            }else{
             pn_VMs vms = new pn_VMs(selected[1], address, port, ks, kspwd, user, userpwd);
             pn_hv.removeAll();
             vms.setBounds(0, 0, pn_hv.getWidth(), pn_hv.getHeight());
             pn_hv.add(vms);
             pn_hv.updateUI();
             vms.loadData();
            }
        }
    }//GEN-LAST:event_cmb_hvsItemStateChanged

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JComboBox cmb_hvs;
    private javax.swing.JPanel pn_hv;
    // End of variables declaration//GEN-END:variables

    
    public boolean loadData() {
        DefaultComboBoxModel model = new DefaultComboBoxModel();
        model.addElement(new String[]{null,null});
        if (!loadSecrets()) {
            return false;
        }
        
        SSocketTools st = new SSocketTools(address, port, ks, kspwd, user, userpwd);
        if (!st.initSocket()) {
            int status = Connection.checkServer(address, port, ks, kspwd, user, kspwd, false);
            pn_Info.Load((JPanel) this.getParent(), this, "Error connecting to server",
                    "Impossible connect to the server <p> Message error :: " + Connection.getErrorDescription(status),
                    pn_Info.ICON_ERROR);
            
            return false;
        }
        if (!Server.startConnection(st)) {
            pn_Info.Load((JPanel) this.getParent(), this, "Error connecting to server",
                    "It was impossible to connect to the server", pn_Info.ICON_ERROR);
            st.closeAll();
            Connection.removeUserSecret(address);
            return false;
        }
        ArrayList<String> hvs = Server.getHypervisors(st);
        for (String hv : hvs) {
            Server.enterHVMode(st, hv);
            try {
                st.sendLine(CMD.CHARS.QUESTION + "getenginename");
                String answer = st.readLine(CMD.ANSWER);
                model.addElement(new String[]{answer, hv});
                Server.exitHVMode(st);
            } catch (IOException ex) {
                pn_Info.Load((JPanel) this.getParent(), this, "Error getting Hypervisor names",
                        "There was a problem while it was recollect hypervisor names. Maybe was a connexion error <p> Error was: "
                        + ex.getMessage(), pn_Info.ICON_ERROR);
                st.closeAll();
                return false;
            } catch (IllegalStatement ex) {
                pn_Info.Load((JPanel) this.getParent(), this, "Error getting Hypervisor names",
                        "Servers sent an illegal statement. Check if blasar server is an old version"
                        + ex.getMessage(), pn_Info.ICON_ERROR);
                st.closeAll();
                return false;
            }
        }
        Server.closeServer(st);
        st.closeAll();
        cmb_hvs.setModel(model);
        cmb_hvs.setRenderer(new cmbRenderer());
        loadServerPanel();
        return true;
    }

    private boolean loadSecrets() {
        ks = Connection.getKeyStore(address);
        kspwd = Connection.getKeyStorePWD(address);
        userpwd = Connection.getUserPwd(address);

        if (ks == null) {
            ks = Connection.gkeystore;
            if (kspwd == null) {
                kspwd = Connection.gkssecret;
            }
            dg_KeyStore dks = new dg_KeyStore(null, true, address);
            dks.setHeader(ks == null ? "Insert your KeyStore" : "Check your KeyStore");
            dks.setData(ks, kspwd);
            dks.setVisible(true);
            ks = dks.getKeyStore();
            kspwd = dks.getPassword();
            if (ks == null) {
                return false;
            }
        }
        boolean dialoguser = false;
        if (!Connection.isDNIe(address)) {
            user = Connection.getUserName(address);
            if (user == null) {
                user = Connection.guser;
                dialoguser = true;
            }

        } else {
            user = "";
        }
        if (userpwd == null) {
            userpwd = Connection.gusersecret;
        }
        if (dialoguser) {
            dg_Username dun = new dg_Username(null, true, address);
            dun.setHeader(user == null ? "Insert your login data" : "Check your login data");
            dun.setData(user, userpwd);
            dun.setVisible(true);
            user = dun.getUserName();
            userpwd = dun.getPassword();
            if (user == null) {
                return false;
            }
        }
        return true;
    }

    private void loadServerPanel() {
        pn_ServerData pn_serverData = new pn_ServerData(address, port, ks, kspwd, user, userpwd);
        pn_serverData.setBounds(0, 0, pn_hv.getWidth(), pn_hv.getHeight());
        pn_hv.removeAll();
        pn_hv.add(pn_serverData);
        pn_serverData.loadData();
        pn_hv.updateUI();
    }
    
    class cmbRenderer extends JLabel implements ListCellRenderer{

        private Icon getHIcon(String code){
            String imagepath;
            if(code.equals("VBX")){
                imagepath = "/kuasar/plugin/servermanager/icons/nogpl/virtualbox.png";
            }else if(code.equals("VMW")){
                imagepath = "/kuasar/plugin/servermanager/icons/nogpl/vmware.png";
            }else if (code.equals("QEM")){
                imagepath = "/kuasar/plugin/servermanager/icons/nogpl/qemu.png";
            }else if (code.equals("XEN")){
                imagepath = "/kuasar/plugin/servermanager/icons/nogpl/xen.png";
            }else if (code.equals("VPC")){
                imagepath = "/kuasar/plugin/servermanager/icons/nogpl/virtualpc.png";
            }else{
                imagepath = "/kuasar/plugin/servermanager/icons/nogpl/unknownhv.png";
            }
            return new javax.swing.ImageIcon(getClass().getResource(imagepath));
        }
        @Override
        public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
            String[] data = (String[]) value;
            if(data[0] == null){
                setText("Server");
                setIcon(new javax.swing.ImageIcon(getClass().getResource("/kuasar/plugin/servermanager/icons/home22.png")));
                return this;
            }
            setText(data[0]);
            setIcon(getHIcon(data[1]));
            return this;
        }
    }
}
